﻿using System;
using Dune.Business.Domain;
using Dune.Business.Domain.AssemblyCodes;
using Dune.Business.Domain.Dictionaries;
using Dune.Business.Domain.Forum;
using Dune.Business.Domain.Users;
using Dune.Business.Security;
using Dune.Common.ComponentModel;
using Dune.Common.Services;
using Dune.Common.Utils;
using Dune.DAL.Common.Config;
using Dune.DAL.Common.SessionManagment;
using Dune.DAL.Managers;
using NHibernate;
using NHibernate.Cfg;
using NHibernate.Type;
using Environment = NHibernate.Cfg.Environment;

namespace Dune.DAL
{
    public class Initializer
    {
        public static void Setup(bool useCache)
        {


            // setup NHibernate

            Configuration cfg = new Configuration();

            cfg.Properties["hibernate.connection.provider"] = "NHibernate.Connection.DriverConnectionProvider";
            cfg.Properties["hibernate.connection.isolation"] = "ReadCommitted";
            cfg.Properties["hibernate.dialect"] = "NHibernate.Dialect.MsSql2000Dialect";
            cfg.Properties["hibernate.connection.driver_class"] = "NHibernate.Driver.SqlClientDriver";
            cfg.Properties["hibernate.use_outer_join"] = "true";

            if (useCache)
            {
                cfg.Properties["hibernate.cache.use_second_level_cache"] = "true";
                cfg.Properties["hibernate.cache.use_query_cache"] = "true";
                cfg.Properties["hibernate.cache.provider_class"] = "NHibernate.Caches.SysCache.SysCacheProvider, NHibernate.Caches.SysCache";
                //            cfg.Properties["hibernate.cache.provider_class"] = "NHibernate.Caches.Prevalence.PrevalenceCacheProvider, NHibernate.Caches.Prevalence";
                //                cfg.Properties["hibernate.cache.provider_class"] = "NHibernate.Cache.HashtableCacheProvider, NHibernate";                
            }


            DALSection dalSection = (DALSection)System.Configuration.ConfigurationManager.GetSection("dal");
            if (dalSection == null)
                throw new ApplicationException("dal section missed");
            cfg.Properties["hibernate.connection.connection_string"] =
                dalSection.ConnectionString;



            cfg.AddAssembly("Dune.DAL");



            ISessionFactory factory = cfg.BuildSessionFactory();

            Locator.AddService<ISessionFactory>(factory);

            Locator.AddService<EntityCodeManager>(new EntityCodeManager());

            // setup managers
            // TODO: find managers by Reflection API
            Locator.AddService<IUserManager>(new UserManager());
            Locator.AddService<IThemeManager>(new ThemeManager());
            Locator.AddService<IPostManager>(new PostManager());
            Locator.AddService<IInviteManager>(new InviteManager());
            Locator.AddService<IDictionariesManager>(new DictionariesManager());
            Locator.AddService<IUserPersonManager>(new UserPersonManager());

            EntityLoader loader = new EntityLoader();
            Locator.AddService<IEntityLoader>(loader);
            Locator.AddService<IEntitySaver>(loader);



            // interceptors
            Locator.AddService<IInterceptorProvider>(new SessionInterceptor());


            // AssemblyStorage
            AssemblyStorage assemblyStorage = new AssemblyStorage();
            Locator.AddService<IAssemblyRepository>(assemblyStorage);
            Locator.AddService<IAssemblyCodeManager>(assemblyStorage);

        }

        private static void AddToTypeOfName(string key, IType type)
        {
            // this is hack
            ReflectionUtils.InvokeStatic(typeof(TypeFactory), "AddToTypeOfName", key, type);
        }
    }
}
